/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright @ Huawei Technologies Co., Ltd. 2022-2022. ALL rights reversed.
 */
#ifndef _KERNEL_FAULT_NOTIFIER_H_
#define _KERNEL_FAULT_NOTIFIER_H_

/*
 *  the kernel fault notification types which pass through
 *  to the 2nd parameter in notifier_fn_t.
 */
#include <linux/notifier.h>

/*
 *	Atomic notifier chain routines.  Registration and unregistration
 *	use a spinlock, and call_chain is synchronized by RCU (no locks).
 */
enum tagKERNEL_FAULT_TYPES_E {
	KERNEL_FAULT_DIE	= 1,
	KERNEL_FAULT_OOM	= 2,
	KERNEL_FAULT_HARDLOCKUP = 3,
	KERNEL_FAULT_SOFTLOCKUP = 4,
	KERNEL_FAULT_PANIC  = 5,
	KERNEL_FAULT_VMALLOC_OOM = 6
};

#ifdef CONFIG_EULEROS_KERNEL_FAULT_NOTIFIER
/**
 *	register_kernel_fault_notifier - Add notifier to an atomic notifier chain
 *	@nb: New entry in notifier chain
 *
 *	Adds a notifier to an atomic notifier chain.
 *	If multiple exceptions occur concurrently, kernel fault notifier will
 *	ensure that notification only once.
 *
 *	Returns zero on success or %-EINVAL on failure.
 */
int register_kernel_fault_notifier(struct notifier_block *nb);

/**
 *	unregister_kernel_fault_notifier - Remove notifier from an atomic notifier chain
 *	@nb: Entry to remove from notifier chain
 *
 *	Removes a notifier from an atomic notifier chain.
 *
 *	Returns zero on success or %-ENOENT or %-EINVAL on failure.
 */
int unregister_kernel_fault_notifier(struct notifier_block *nb);

extern void notify_kernel_fault(enum tagKERNEL_FAULT_TYPES_E type);
extern void do_notify_kernel_fault(void);
#else
static inline void notify_kernel_fault(enum tagKERNEL_FAULT_TYPES_E type) {};
static inline void do_notify_kernel_fault(void) {};
#endif /* CONFIG_EULEROS_KERNEL_FAULT_NOTIFIER */
#endif /* _KERNEL_FAULT_NOTIFIER_H_ */
